<template>
  <view class="scraping-happy" id="container">
    <canvas
      :style="{ width: width + 'px', height: height + 'px' }"
      canvas-id="scraping-happy"
      class="scraping__canvas"
      :disable-scroll="true"
      @touchstart="touchstart"
      @touchmove="touchmove"
      @touchend="touchend"
    />
    <cover-view class="scraping__view">
      谢谢惠顾
    </cover-view>
  </view>
</template>

<script>
/** @name 水印配置默认值 **/
const WATERMARK = {
  text: '刮一刮',
  fontSize: 14,
  color: '#C5C5C5',
}
/** @name 标题配置默认值 **/
const TITLE = {
  text: '刮一刮',
  fontSize: 26,
  color: '#888888',
}
/** 
 * @name 涂层配置默认值 
 * @property { string } color 涂层颜色
 * @property { number } drawSize 清除涂层的画笔大小
 */
const MASK = {
  color: '#DDDDDD',
  drawSize: 20,
}
/** @name 容错值，解决出行边框问题 **/
const TOLERANT = 0;

let ctx = null;

export default {
  props: {
    /** @name 涂层设置 **/
    mask: {
      type: [String, Object],
    },
    /** @name 水印设置 **/
    watermark: {
      type: [String, Object],
    },
    /** @name 提示文字 **/
    title: {
      type: [String, Object],
    },
    /** @name 刮开百分之多少直接消除图层，为0的时候不消除 **/
    percentage: {
      type: Number,
      default: 60,
    },
  },
  data() {
    return {
      width: 0,
      height: 0,
      touchX: 0,
      touchY: 0
    }
  },
  computed: {
    maskSetting() {
      return {
        ...MASK,
        ...(typeof this.mask === 'object' ? this.mask : { text: this.mask }),
      }
    },
    watermarkSetting() {
      return {
        ...WATERMARK,
        ...(typeof this.watermark === 'object' ? this.watermark : { text: this.watermark }),
      };
    },
    titleSetting() {
      return {
        ...TITLE,
        ...(typeof this.title === 'object' ? this.title : { text: this.title }),
      };
    }
  },
  mounted() {
    // 获取画布实例
    ctx = uni.createCanvasContext('scraping-happy', this);
    this.init();
  },
  methods: {
    /** @name 初始化 **/
    init() {
      const query = uni.createSelectorQuery().in(this);
      query
        .select('#container')
        .boundingClientRect(({ width, height }) => {
          this.width = width;
          this.height = height;
          setTimeout(() => {
            this.initCanvas();
          }, 20)
        })
        .exec();
    },
    /** @name 初始化canvas状态 **/
    initCanvas() {
      const { width, height } = this;
      console.log('width, height', width, height)
      // 清空矩形内容
      ctx.clearRect(0, 0, width, height);
      // 设置画笔颜色
      ctx.setFillStyle(this.maskSetting.color);
      // 绘制矩形
      ctx.fillRect(0, 0, width , height);
      // 绘制水印
      // this.drawWatermark();
      // 绘制提示文字
      // this.drawTitle();
      // 绘制到canvas身上
      ctx.draw();
    },
    /** @name 绘制水印 **/
    drawWatermark() {
      if (!this.watermarkSetting.text) return;
      // 保存当前的绘图上下文
      ctx.save();
      // 旋转
      ctx.rotate((-10 * Math.PI) / 180);
      // 水印具体绘制过程
      const { width, height } = this;
      const watermarkWidth = this.watermarkSetting.text.length * this.watermarkSetting.fontSize;
      let x = 0;
      let y = 0;
      let i = 0;
      while ((x <= width * 5 || y <= height * 5) && i < 300) {
        ctx.setFillStyle(this.watermarkSetting.color);
        ctx.setFontSize(this.watermarkSetting.fontSize);
        ctx.fillText(this.watermarkSetting.text, x, y);
        x += watermarkWidth + watermarkWidth * 1.6;
        if (x > width && y <= height) {
          x = -Math.random() * 100;
          y += this.watermarkSetting.fontSize * 3;
        }
        i++;
      }
      ctx.restore();
    },
    /** @name 绘制提示文字 **/
    drawTitle() {
      if (!this.titleSetting.text) return;
      ctx.setTextAlign('center');
      ctx.setTextBaseline('middle');
      ctx.setFillStyle(this.titleSetting.color);
      ctx.setFontSize(this.titleSetting.fontSize);
      ctx.fillText(this.titleSetting.text, this.width / 2, this.height / 2);
    },
    /** @name 触摸事件 **/
    touchstart(e) {
      this.touchX = e.touches[0].x;
      this.touchY = e.touches[0].y;
    },
    async touchmove(e) {
      // 把画笔到画布中的指定点
      ctx.moveTo(this.touchX, this.touchY);
      // 清除涂层
      ctx.clearRect(this.touchX, this.touchY, this.maskSetting.drawSize, this.maskSetting.drawSize);
      ctx.draw(true);
      // 记录移动点位
      this.touchX = e.touches[0].x;
      this.touchY = e.touches[0].y;

      // if (this.percentage > 0) {
      //   const clearPercent = await this.getClearMaskPercent();
      //   console.log('clearPercent', clearPercent)
      // } 
    },
    async touchend() {
      if (this.percentage > 0) {
        const clearPercent = await this.getClearMaskPercent();
        if (clearPercent >= this.percentage) {
          ctx.moveTo(0, 0);
          ctx.clearRect(0, 0, this.width, this.height);
          ctx.stroke();
          ctx.draw(true);
          console.log('touchend')
        }
      }
    },
    /** @name 计算被清除的涂层百分比 **/
    getClearMaskPercent() {
      return new Promise(resolve => {
        uni.canvasGetImageData({
          canvasId: 'scraping-happy',
          x: 0,
          y: 0,
          width: this.width,
          height: this.height,
          success: res => {
            // 区域内所有点的像素信息，它是一个数组，数组中每 "4" 项表示一个点的 rgba 值
            const allPointPixels = res.data;
            // 储存被清除的点-点的透明度
            const clearPoint = [];
            // 取透明度来判断，如果透明度值小于一半，则判断为该点已经被清除
            for (let i = 0; i < allPointPixels.length; i += 4) {
              if (allPointPixels[i + 3] < 128) {
                clearPoint.push(allPointPixels[i + 3]);
              }
            }
            // 已被清除的百分比 = 清除的点 / 全部的点
            const percent = (
              (clearPoint.length / (allPointPixels.length / 4)) *
              100
            ).toFixed(2);
            resolve(percent);
          },
          fail: e => {
            console.log('canvasGetImageData', e);
          },
        }, this);
      });
    },
    /** @name 重置 **/
    reset() {
      this.initCanvas();
      this.touchX = 0;
      this.touchY = 0;
    }
  }
};
</script>

<style>
.scraping-happy {
  width: 300rpx;
  height: 200rpx;
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
}
.scraping__canvas {
  position: absolute;
  z-index: 10;
  background-color: red;
  display: inline-block;
}
.scraping__view {
  position: absolute;
  z-index: 1;
  color: #f29100;
  font-size: 20px;
  font-weight: bold;
}
</style>
